package io.renren.config;

import javax.sql.DataSource;

import org.beetl.core.GroupTemplate;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.beetl.sql.core.ClasspathLoader;
import org.beetl.sql.core.Interceptor;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.UnderlinedNameConversion;
import org.beetl.sql.core.db.DBStyle;
import org.beetl.sql.core.db.MySqlStyle;
import org.beetl.sql.core.db.OracleStyle;
import org.beetl.sql.core.db.SqlServerStyle;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.ext.spring4.BeetlSqlDataSource;
import org.beetl.sql.ext.spring4.BeetlSqlScannerConfigurer;
import org.beetl.sql.ext.spring4.SqlManagerFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;


@Configuration
public class BeetlsqlConfig {
//	private static final Map<String,DBStyle> DBStyleMap = new HashMap<String,DBStyle>(){
//		private static final long serialVersionUID = -3777459974446309899L;
//
//		{
//			DBStyleMap.put("mysql",new MySqlStyle());
//			DBStyleMap.put("oracle",new OracleStyle());
//			DBStyleMap.put("sqlserver",new SqlServerStyle());
//			}
//		};

	@Bean(initMethod = "init", name = "beetlConfig")
    public BeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration(Environment env) {

        BeetlGroupUtilConfiguration beetlGroupUtilConfiguration = new BeetlGroupUtilConfiguration();
        ResourcePatternResolver patternResolver = ResourcePatternUtils.getResourcePatternResolver(new DefaultResourceLoader());

        try {
//        	BeetlProperties beetl = beetlSqlProperties.getBeetl();
            ClasspathResourceLoader cploder = new ClasspathResourceLoader(env.getProperty("beetlSql.templates"));
            beetlGroupUtilConfiguration.setResourceLoader(cploder);

            beetlGroupUtilConfiguration.setConfigFileResource(patternResolver.getResource(env.getProperty("beetlSql.configFileResource")));
            
            return beetlGroupUtilConfiguration;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
	
//    @Bean(name = "beetlViewResolver")
//    public BeetlSpringViewResolver getBeetlSpringViewResolver(@Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration) {
//        BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
//        beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
//        beetlSpringViewResolver.setOrder(0);
//        beetlSpringViewResolver.setConfig(beetlGroupUtilConfiguration);
//        return beetlSpringViewResolver;
//    }
	
    @Bean(name="groupTemplate")
    public GroupTemplate getGroupTemplate(@Qualifier("beetlConfig") BeetlGroupUtilConfiguration beetlGroupUtilConfiguration){
    	 GroupTemplate group = beetlGroupUtilConfiguration.getGroupTemplate();
    	 return group;
    }

	@Bean(name = "beetlSqlScannerConfigurer")
    public BeetlSqlScannerConfigurer getBeetlSqlScannerConfigurer(@Qualifier("sqlManagerFactoryBean") SqlManagerFactoryBean fb,Environment env) {
        BeetlSqlScannerConfigurer conf = new BeetlSqlScannerConfigurer();
        conf.setBasePackage(env.getProperty("beetlSql.basePackage"));
        conf.setDaoSuffix(env.getProperty("beetlSql.daoSuffix"));
        conf.setSqlManagerFactoryBeanName(env.getProperty("beetlSql.sqlManagerFactoryBeanName"));

        SQLManager sql;
        try {
            sql = (SQLManager) fb.getObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
 
        return conf;
    }

    @Bean(name = "sqlManagerFactoryBean")
    @Primary
    public SqlManagerFactoryBean getSqlManagerFactoryBean(@Qualifier("datasource") DataSource datasource,Environment env) {
        SqlManagerFactoryBean factory = new SqlManagerFactoryBean();

        BeetlSqlDataSource source = new BeetlSqlDataSource();
        source.setMasterSource(datasource);
        factory.setCs(source);
        String dbStyle = env.getProperty("beetlSql.dbStyle");
        DBStyle db = null;
        switch (dbStyle) {
		case "mysql":
			db = new MySqlStyle();
			break;
		case "oracle":
			db = new OracleStyle();
			break;
		case "sqlserver":
			db = new SqlServerStyle();
			break;
		default:
			break;
		}
        factory.setDbStyle(db);
        factory.setInterceptors(new Interceptor[]{new DebugInterceptor()});
        // 数据库命名跟java命名一样，所以采用DefaultNameConversion，还有一个是UnderlinedNameConversion，下划线风格的，
        factory.setNc(new UnderlinedNameConversion());
        // sql语句放在classpagth的/sql 目录下
        factory.setSqlLoader(new ClasspathLoader(env.getProperty("beetlSql.sqlLoader")));

        return factory;
    }
    
    @Bean(name = "datasource")
	public DataSource druidDataSource(Environment env) {
		DruidDataSource druidDataSource = new DruidDataSource();
		
		druidDataSource.setDriverClassName(env.getProperty("druid.driverClassName"));
		druidDataSource.setUrl(env.getProperty("druid.url"));
		druidDataSource.setUsername(env.getProperty("druid.username"));
		druidDataSource.setPassword(env.getProperty("druid.password"));
		druidDataSource.setValidationQuery(env.getProperty("druid.validationQuery"));
		druidDataSource.setInitialSize(5);
		druidDataSource.setMaxActive(10);
		return druidDataSource;
	}
    
    @Bean(name="txManager")  
    public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("datasource") DataSource datasource) {  
    	DataSourceTransactionManager dsm = new DataSourceTransactionManager();
    	dsm.setDataSource(datasource);
    	return dsm;
    } 
}
